import T01_Utils.JDBCUtils;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Collection;

/**
 * 使用PreparedStatement实现批量数据的操作
 *
 * update、delete本身就具有批量操作的效果
 * 此时的批量操作,主要指的是批量插入,使用PreparedStatement 如何实现更高效的批量插入？
 *
 * 题目:向goods表中插入20000条数据
 * create  table  goods(
 *           id int primary key  auto_increment,
 *           name varchar(25)
 * )
 *
 * 方式一:使用Statement
 * Connection conn=JDBCUtils.getConnection()
 * Statement st=conn.createStatement()
 * for(int i=1;i<20000;i++){
 *   string sql="insert into goods(name) values('name_"+i+"')"
 *   st.execute(sql);
 * }
 *
 * 方式二:使用PreparedStatement
 *   IDE:idea 测试数据如下
 *   Statement:24652ms
 *   PreparedStatement:23130ms
 *
 * 方式三:
 */
public class InsertTest {

    /**
     * 方式二:使用PreparedStatement
     */
    @Test
    public void  testInsert01(){
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            long start = System.currentTimeMillis();
            conn= JDBCUtils.getConnection();
             String sql="insert into  goods(name) values(?)";
             ps = conn.prepareStatement(sql);
             for(int i=1;i<20000;i++){
                ps.setObject(1,"name_"+i);
                ps.execute();
            }
            long end = System.currentTimeMillis();
            System.out.println("花费的时间为:"+(end-start));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(conn,ps);
        }
    }

    /**
     * 方式三:原来是一条操作一次,现在我们攒一攒在一次执行500条
     * 修改1:1.addBatch()、2.executeBatch()、clearBatch()
     * 修改2:mysql服务器默认是关闭批处理的，我们需要通过一个参数，让mysql开启批处理的支持。
     *   		 ?rewriteBatchedStatements=true 写在配置文件的url后面
     * 修改3:使用更新的mysql 驱动：mysql-connector-java-5.1.37-bin.jar
     */
    @Test
    public void  testInsert02(){
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            long start = System.currentTimeMillis();
            conn= JDBCUtils.getConnection();
            String sql="insert into  goods(name) values(?)";
            ps = conn.prepareStatement(sql);
            for(int i=1;i<20000;i++){
                ps.setObject(1,"name_"+i);
                //1.攒sql
                if(i%500==0){
                    //2.执行batch
                    ps.executeBatch();

                    //3.清空batch
                    ps.clearBatch();
                }
                //除不尽的情况下在判断一次


            }
            long end = System.currentTimeMillis();
            System.out.println("花费的时间为:"+(end-start));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(conn,ps);
        }
    }


    /**
     * 方式四:在方式三的基础上操作
     * 使用Connection 的 setAutoCommit(false)  /  commit()
     * myslq默认是----自动提交    处理思路关闭自动提交
     */
    @Test
    public void  testInsert03(){
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            long start = System.currentTimeMillis();
            conn= JDBCUtils.getConnection();
            conn.setAutoCommit(false);
            String sql="insert into  goods(name) values(?)";
            ps = conn.prepareStatement(sql);
            for(int i=1;i<20000;i++){
                ps.setObject(1,"name_"+i);
                //1.攒sql
                if(i%500==0){
                    //2.执行batch
                    ps.executeBatch();  //自动数据提交 执行一次 自己往数据库提交一次    关闭自动提交
                    //3.清空batch
                    ps.clearBatch();
                }
                //除不尽的情况下在判断一次
            }
            //提交数据
            conn.commit();
            long end = System.currentTimeMillis();
            System.out.println("花费的时间为:"+(end-start));
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.closeResource(conn,ps);
        }
    }
}
